# -*- coding: utf-8 -*-
# @Time    : 2024/6/24 18:07
# @Author  : yujiahao
# @File    : 08_pandas_data_format_index.py
# @description:pandas数据显示格式和字符串


import pandas as pd
import numpy as np


# todo 1、Pandas设置数据显示格式


def pands_data_format():
    """
    在用 Pandas 做数据分析的过程中，总需要打印数据分析的结果，
    如果数据体量较大就会存在输出内容不全（部分内容省略）或者换行错误等问题。
    Pandas 为了解决上述问题，允许你对数据显示格式进行设置。
    下面列出了五个用来设置显示格式的函数，分别是：get_option(), set_option(), reset_option(), describe_option(), option_context()。

    它们的功能介绍如下：

    函数名称         说明
    ----------------------------------------------------------------------
    get_option      获取解释器的默认参数值。
    set_option      更改解释器的默认参数值。
    reset_option    解释器的参数重置为默认值。
    describe_option 输出参数的描述信息。
    option_context  临时设置解释器参数，当退出使用的语句块时，恢复为默认值。

    常用参数项：
    参数                      说明
    ----------------------------------------------------------------------
    display.max_rows          最大显示行数，超过该值用省略号代替，为None时显示所有行。
    display.max_columns       最大显示列数，超过该值用省略号代替，为None时显示所有列。
    display.expand_frame_repr 输出数据宽度超过设置宽度时，表示是否对其要折叠，False不折叠，True要折叠。
    display.max_colwidth      单列数据宽度，以字符个数计算，超过时用省略号表示。
    display.precision         设置输出数据的小数点位数。
    display.width             数据显示区域的宽度，以总字符数计算。
    display.show_dimensions   当数据量大需要以truncate（带引号的省略方式）显示时，该参数表示是否在最后显示数据的维数，默认 True 显示，False 不显示。
    """

    # 示例数据
    data = {
        'Name': ['Alice', 'Bob', 'Charlie', 'David', 'Edward'],
        'Age': [24, 27, 22, 32, 29],
        'Score': [85.5, 90.3, 78.9, 88.7, 92.1]
    }
    df = pd.DataFrame(data)

    # get_option: 获取当前的显示选项值（该函数接受单一参数，用来获取显示上限的行数或者列数）
    print("get_option() 示例:")
    max_rows = pd.get_option("display.max_rows")
    print(f"默认的最大显示行数: {max_rows}")

    max_columns = pd.get_option("display.max_columns")
    print(f"默认的最大显示列数: {max_columns}")

    # set_option: 设置显示选项值（该函数用来更改要默认显示的行数和列数）
    print("\nset_option() 示例:")
    pd.set_option("display.max_rows", 70)
    print(f"设置后的最大显示行数: {pd.get_option('display.max_rows')}")

    pd.set_option("display.max_columns", 40)
    print(f"设置后的最大显示列数: {pd.get_option('display.max_columns')}")

    # reset_option: 重置显示选项值为默认值（该方法接受一个参数，并将修改后的值设置回默认值。）
    print("\nreset_option() 示例:")
    pd.reset_option("display.max_rows")
    print(f"重置后的最大显示行数: {pd.get_option('display.max_rows')}")

    # describe_option: 输出显示选项的描述信息（该方法输出参数的描述信息。）
    print("\ndescribe_option() 示例:")
    pd.describe_option("display.max_rows")

    # option_context: 临时设置显示选项值（option_context() 上下文管理器，用于临时设置 with 语句块中的默认显示参数。当退出 with 语句块时，参数值会自动恢复。）
    print("\noption_context() 示例:")
    with pd.option_context("display.max_rows", 10):
        print(f"临时设置的最大显示行数: {pd.get_option('display.max_rows')}")
        print(df)

    # 退出with语句块后，显示选项值恢复为默认值
    print(f"退出with语句块后，最大显示行数恢复为默认值: {pd.get_option('display.max_rows')}")
    print(df)

    # 常用参数项示例
    print("\n常用参数项示例:")
    pd.set_option("display.max_rows", 10)
    pd.set_option("display.max_columns", 10)
    pd.set_option("display.expand_frame_repr", False)
    pd.set_option("display.max_colwidth", 50)
    pd.set_option("display.precision", 2)
    pd.set_option("display.width", 100)
    pd.set_option("display.show_dimensions", True)

    print(f"最大显示行数: {pd.get_option('display.max_rows')}")
    print(f"最大显示列数: {pd.get_option('display.max_columns')}")
    print(f"是否折叠显示: {pd.get_option('display.expand_frame_repr')}")
    print(f"最大列宽: {pd.get_option('display.max_colwidth')}")
    print(f"小数点精度: {pd.get_option('display.precision')}")
    print(f"显示宽度: {pd.get_option('display.width')}")
    print(f"是否显示维数: {pd.get_option('display.show_dimensions')}")

    '''
    在数据分析过程中，很多时候需要从数据表中提取出相应的数据，而这么做的前提是需要先“索引”出这一部分数据。
    虽然通过 Python 提供的索引操作符"[]"和属性操作符"."可以访问 Series 或者 DataFrame 中的数据，但这种方式只适应与少量的数据，
    为了解决这一问题，Pandas 提供了两种类型的索引方式来实现数据的访问。
    
    
    
        方法名称	        说明
        .loc[]	    基于标签索引选取数据
        .iloc[]	    基于整数索引选取数据
        
    
    df.loc[] 只能使用标签索引，不能使用整数索引。当通过标签索引的切片方式来筛选数据时，它的取值前闭后闭，也就是只包括边界值标签（开始和结束）。
    
        .loc[] 具有多种访问方法，如下所示：
            一个标量标签
            标签列表
            切片对象
            布尔数组
    
    loc[] 接受两个参数，并以','分隔。第一个位置表示行，第二个位置表示列。
  
  df.iloc[] 只能使用整数索引，不能使用标签索引，通过整数索引切片选择数据时，前闭后开(不包含边界结束值)。同 Python 和 NumPy 一样，它们的索引都是从 0 开始。

    .iloc[] 提供了以下方式来选择数据：
        1) 整数索引
        2) 整数列表
        3) 数值范围      
    '''


def pandas_locs():
    # 创建一组数据
    data = {'name': ['John', 'Mike', 'Mozla', 'Rose', 'David', 'Marry', 'Wansi', 'Sidy', 'Jack', 'Alic'],
            'age': [20, 32, 29, np.nan, 15, 28, 21, 30, 37, 25],
            'gender': [0, 0, 1, 1, 0, 1, 0, 0, 1, 1],
            'isMarried': ['yes', 'yes', 'no', 'yes', 'no', 'no', 'no', 'yes', 'no', 'no']}
    label = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j']
    df = pd.DataFrame(data, index=label)
    print(df)

    print('''\n-----------------------------------☆☆☆分割线☆☆☆----------------------------------------\n''')

    # 对行操作,这里注意都是闭区间，包含a 和 d
    print(df.loc['a':'d', :])  # 等同于df.loc['a':'d']

    print('''\n-----------------------------------☆☆☆分割线☆☆☆----------------------------------------\n''')

    # 这里相当于name整列取值
    print(df.loc[:, 'name'])

    print('''\n-----------------------------------☆☆☆分割线☆☆☆----------------------------------------\n''')

    # 对行和列同时操作
    print(df.loc[['a', 'b', 'f', 'h'], ['name', 'isMarried']])

    print('''\n-----------------------------------☆☆☆分割线☆☆☆----------------------------------------\n''')

    df = pd.DataFrame(np.random.randn(4, 4), index=['a', 'b', 'c', 'd'], columns=['A', 'B', 'C', 'D'])
    # 返回一组布尔值
    print(df.loc['b'] > 0)


def pandas_ilocs():
    data = {'name': ['John', 'Mike', 'Mozla', 'Rose', 'David', 'Marry', 'Wansi', 'Sidy', 'Jack', 'Alic'],
            'age': [20, 32, 29, np.nan, 15, 28, 21, 30, 37, 25],
            'gender': [0, 0, 1, 1, 0, 1, 0, 0, 1, 1],
            'isMarried': ['yes', 'yes', 'no', 'yes', 'no', 'no', 'no', 'yes', 'no', 'no']}
    label = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j']
    df = pd.DataFrame(data, index=label)
    print('原始数据：\n', df)

    print('''\n-----------------------------------☆☆☆分割线☆☆☆----------------------------------------\n''')
    # 行索引2往后的所有值
    print(df.iloc[2:, ])

    print('''\n-----------------------------------☆☆☆分割线☆☆☆----------------------------------------\n''')

    df = pd.DataFrame(np.random.randn(8, 4), columns=['A', 'B', 'C', 'D'])
    # [行索引]，[列标签]
    print(df.iloc[[1, 3, 5], [1, 3]])
    print(df.iloc[1:3, :])
    print(df.iloc[:, 1:3])


def main():
    # pands_data_format()
    pandas_locs()
    # pandas_ilocs()


if __name__ == "__main__":
    main()
